home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / HydraCom / hydracom-source.lha / hydracom.c < prev    next >
C/C++ Source or Header  |  1996-09-05  |  32KB  |  859 lines

  1. /*=============================================================================
  2.  
  3.                               HydraCom Version 1.00
  4.  
  5.                          A sample implementation of the
  6.                    HYDRA Bi-Directional File Transfer Protocol
  7.  
  8.                              HydraCom was written by
  9.                    Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT
  10.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  11.  
  12.                        The HYDRA protocol was designed by
  13.                  Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT and
  14.                              Joaquim H. Homrighausen
  15.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  16.  
  17.  
  18.   Revision history:
  19.   06 Sep 1991 - (AGL) First tryout
  20.   .. ... .... - Internal development
  21.   11 Jan 1993 - HydraCom version 1.00, Hydra revision 001 (01 Dec 1992)
  22.  
  23.  
  24.   DISCLAIMER
  25.  
  26.   This program is provided "as is" and comes with no warranties of any
  27.   kind, either expressed or implied. In no event shall the authors be
  28.   liable to you or anyone else for any damages, including any lost
  29.   profits, lost savings or other incidental or consequential damages
  30.   arising out of the use or inability to use this software.
  31.  
  32.  
  33.   HYDRACOM / SOURCE LICENSE
  34.  
  35.   HydraCom, its associated utilities (HydraCfg) and the HydraCom
  36.   sourcecode may be freely distributed, copied and used, no fee charged.
  37.   All files, executables and sourcecode remain the copyrighted property
  38.   of Arjen G. Lentz and LENTZ SOFTWARE-DEVELOPMENT.
  39.   The distribution archives should remain intact with no files removed
  40.   or modified. For special purposes, it is allowed to repack the
  41.   archives using a different compression system.
  42.  
  43.   HydraCom may be bundled up with for instance terminal or BBS packages,
  44.   even commercial ones, provided the buyer/user is clearly informed
  45.   about the fact that Hydra and HydraCom are free, not owned by the
  46.   distributor/retailer in question, and is not included in any possible
  47.   charge regarding the rest of the package. This documentation must also
  48.   be present so the user can inform himself about Hydra and HydraCom.
  49.   The same rules apply to inclusion in shareware and CD-ROM libraries.
  50.   In all cases, the author of HydraCom must be given credit in any
  51.   informational screens and literature that contain such information.
  52.  
  53.   The Hydra/HydraCom sourcecode may also be freely used and integrated
  54.   into other software or library, provided this is clearly stated in any
  55.   informational screens and literature pertaining to this program, and
  56.   credit is given to the original author. If the sourcecode of that
  57.   program or library is released or otherwise published, the notices
  58.   present at the top of every Hydra/HydraCom source file must be
  59.   retained in their original unmodified form.
  60.  
  61.   In addition to the above license, everyone using any part of the
  62.   sourcecode, programs or files is fully bound by the general license of
  63.   the Hydra protocol as present in the Hydra protocol description
  64.   document. For easy reference, the paragraph in question is reprinted
  65.   below.
  66.  
  67.   Any use of, or operation on (including copying/distributing) any of
  68.   the above mentioned files implies full and unconditional acceptance of
  69.   this license and disclaimer.
  70.  
  71.  
  72.   HYDRA PROTOCOL LICENSE
  73.  
  74.   You are granted a license to implement the HYDRA file transfer
  75.   protocol, HYDRA hereafter, in your own programs and/or use the sample
  76.   source code and adapt these to your particular situation and needs;
  77.   subject to the following conditions:
  78.  
  79.    -  You must refer to it as the HYDRA file transfer protocol, and you
  80.       must give credit to the authors of HYDRA in any information
  81.       screens or literature pertaining to your programs that contains
  82.       other such information (credits, your own copyrights, etc.).
  83.  
  84.    -  HYDRA will always remain backwards compatible with previous
  85.       revisions. HYDRA allows for expansion of its features without
  86.       interfering with previous revisions. It is, however, important
  87.       that different people do not expand the protocol in different
  88.       directions. We therefore ask you to contact us if you have any
  89.       needs/ideas regarding HYDRA, so development can be synchronized
  90.       and beneficial to all.
  91.  
  92.    -  If your implementation cannot converse with past or future
  93.       revisions as supplied by us, then you must refer to it as "HYDRA
  94.       derived", or as "a variation of HYDRA", or words to that effect.
  95.  
  96.  
  97.   Hydra protocol design and HydraCom driver:         Hydra protocol design:
  98.   Arjen G. Lentz                                     Joaquim H. Homrighausen
  99.   LENTZ SOFTWARE-DEVELOPMENT                         389, route d'Arlon
  100.   Langegracht 7B                                     L-8011 Strassen
  101.   3811 BT  Amersfoort                                Luxembourg
  102.   The Netherlands
  103.   FidoNet 2:283/512, AINEX-BBS +31-33-633916         FidoNet 2:270/17
  104.   arjen_lentz@f512.n283.z2.fidonet.org               joho@ae.lu
  105.  
  106.   Please feel free to contact us at any time to share your comments about our
  107.   software and/or licensing policies.
  108.  
  109. =============================================================================*/
  110.  
  111. #define MAIN
  112. #include "hydracom.h"
  113.  
  114.  
  115. void main (int argc, char *argv[])
  116. {
  117.         FILE    *ctl;
  118.         char     ctlname[PATHLEN];
  119.         int      err = 0;              /* assume all went well: errorlevel 0 */
  120.         int      ac;
  121.         char    *p;
  122.         register int i, res;
  123.  
  124.         av = (char **) malloc(MAXARGS * ((int) sizeof (char *)));
  125.         port = 0;                                   /* default configuration */
  126.         strcpy(device,"serial.device");    /* OLSEN */
  127.         cur_speed = com_speed = 0U;
  128.         parity = false;
  129.         noinit = nocarrier = dropdtr = false;
  130.         nobell = false;
  131.         mailer = false;
  132.         hdxsession = nooriginator = false;
  133.         hydra_txwindow = hydra_rxwindow = 0L;
  134.         flowflags = 0;
  135.         dcdmask = 0x80;
  136.         noresume = nostamp = false;
  137.         hydra_options = 0x0L;
  138.         result = opuslog = NULL;
  139.         download = "";
  140.         single_file[0] = '\0';
  141.         single_done = false;
  142.         logfp = NULL;
  143.         loglevel = 2;
  144.         opustask = -1;
  145.         didsome = false;
  146. #if !WIN_AGL
  147.         file_x = 0;
  148. #endif
  149.  
  150. #ifdef AMIGA
  151.         {
  152.            extern struct Library *SysBase;
  153.  
  154.            if(SysBase -> lib_Version < 37)
  155.            {
  156.              printf("Sorry, %s requires Kickstart v2.04 or higher!\n",PRGNAME);
  157.              exit(20);
  158.            }
  159.         }
  160. #endif
  161.  
  162. #ifndef AMIGA
  163.         signal(SIGINT,SIG_IGN);                            /* disable Ctrl-C */
  164. #endif    /* AMIGA */
  165.  
  166.         if (!getenv("TZ"))
  167.            putenv("TZ=GMT0");
  168.         tzset();
  169.         dos_sharecheck();
  170.  
  171. #if !WIN_AGL && !defined(AMIGA)
  172. /* HJW The Topspeed gettext and puttext window procedures do have a
  173.    bug in non video mode, at least in version 3.02. The only thing we
  174.    can do is to enable direct viodeo. Also: The clipping window
  175.    module reports always 25 x 80 as the screen dimensions. The bugs
  176.    are reported to JPI
  177. */
  178.  
  179. #ifdef _JPI_
  180.         directvideo = 1;
  181. #else
  182.         directvideo = 0;
  183. #endif
  184. #endif
  185.  
  186.         cprint("%s %s %s; Sample implementation of Hydra revision %03u (%s)\n",
  187.               PRGNAME, VERSION, HC_OS, H_REVISION, h_revdate(H_REVSTAMP));
  188.         cprint("COPYRIGHT (C) 1991-1993 by Arjen G. Lentz; ALL RIGHTS RESERVED\n");
  189.         cprint("HYDRA was designed by Arjen G. Lentz & Joaquim H. Homrighausen\n");
  190.         cprint("\n");
  191.         cprint("Full specifications of the Hydra file transfer protocol are freely available.\n");
  192.         cprint("The sources of this driver have also been released, to which the same license\n");
  193.         cprint("applies as for this executable. See the documentation for further information.\n");
  194.         cprint("\n");
  195.  
  196. #ifndef AMIGA    /* OLSEN */
  197.         if (_osmajor < 3) {
  198.            cprint("Sorry, %s requires DOS 3.0 or higher!\n",PRGNAME);
  199.            exit (2);
  200.         }
  201. #endif    /* AMIGA */
  202.  
  203.         if (argc < 2) {
  204.            cprint("Usage: %s [port N] [device <name>] [speed N] [<options> ...] <command> [<parms> ...]\n",PRGNAME);    /* OLSEN */
  205.            any_key();
  206. #ifdef AMIGA
  207.            cprint("options:  port N          Unit number (default 0)\n");
  208. #else
  209.            cprint("options:  port N          Comport [1..16] (default COM1)\n");
  210. #endif
  211.            cprint("          speed N         Com-speed [300..57600] (default current speed)\n");
  212. #ifdef AMIGA
  213.            cprint("          device <name>   Name of serial device driver to use\n");    /* OLSEN */
  214.            cprint("          priority N      Task priority to use\n");    /* OLSEN */
  215.            cprint("          quiet           Stay quietly in the background\n");    /* OLSEN */
  216. #endif
  217.            cprint("          retries N       Maximum number of retries in case of error (default 10)\n");    /* OLSEN */
  218.            cprint("          line N          Actual line speed (use 'speed' to set comport)\n");
  219.            cprint("          parity          Set 7E1 instead of 8N1 (forces option highbit)\n");
  220.            cprint("          dropdtr         Drop DTR if carrier is lost\n");
  221.            cprint("          nocarrier       Disable carrier detection\n");
  222.            cprint("          noinit          Don't init/deinit FOSSIL driver\n");
  223.            cprint("          handshake <flg> Enable soft (XON/XOFF), hard (RTS/CTS) or both\n");
  224.            cprint("          log <file>      Logfile to log the goings on\n");
  225.            cprint("          level N         Level of logging, 0=max, 6=min (default=2)\n");
  226.            cprint("          result <file>   Log transfer info to DSZ compatible logfile\n");
  227.            cprint("          noresume        Disable receive bad-transfer recovery\n");
  228.            cprint("          nostamp         Don't stamp with original but current filetime\n");
  229.            cprint("          receive <path>  Path to store any received files\n");
  230.            cprint("          nobell          Disable bell noise in Hydra session chat feature\n");
  231. #ifndef AMIGA
  232.            any_key();
  233. #endif
  234.            cprint("link opt: mailer          Mailer mode, used by Dutchie (see documentation)\n");
  235.            cprint("          nooriginator    Not originator, fallback to one-way transfer allowed\n");
  236.            cprint("          hdxlink         Force one-way transfer mode (only with nooriginator)\n");
  237.            cprint("          txwindow N      Transmitter window size (default 0=full streaming)\n");
  238.            cprint("          rxwindow N      Receiver window size (default 0=full streaming)\n");
  239.            cprint("          option xonxoff  HYDRA link option: Escape/strip XON/XOFF characters\n");
  240.            cprint("          option telenet  HYDRA link option: Escape/strip Telenet escape\n");
  241.            cprint("          option ctlchrs  HYDRA link option: Escape/strip ASCII 0-31 and 127\n");
  242.            cprint("          option highctl  HYDRA link option: Apply above three also for 8th bit\n");
  243.            cprint("          option highbit  HYDRA link option: Encode for 7 bit, strip 8th bit\n");
  244.            cprint("commands: send [<fspec> ...]    Send <filespec>/@<ctlfile>/nothing + receive\n");
  245.            cprint("          get [<path>[<name>]]  Only get file(s), if filename is specified, get\n");
  246.            cprint("                                first file (name override) and skip all others\n");
  247.            cprint("          term                  Small terminal + send & AutoStart capability\n");
  248.            cprint("notes:    Options may be abbrev. to 3 chars; Use <exename>.CFG for defaults!\n");
  249.            cprint("          File <exename>.CTL or option -t<n> triggers Opus-external interface\n");
  250.            cprint("          Exit codes: transfer completed = 0, aborted = 1, runtime error = 2\n");
  251.            exit (0);
  252.         }
  253.  
  254.         strcpy(ourname,argv[0]);
  255. #ifdef AMIGA
  256.         strcat(ourname,".");
  257.         pri = 1000;
  258. #else
  259.         ourname[((int) strlen(ourname)) - 3] = '\0';   /* chop off extension */
  260. #endif    /* AMIGA */
  261.         if (getenv("DSZLOG"))
  262.            result = strdup(getenv("DSZLOG"));
  263.  
  264. #ifdef AMIGA
  265.         strcpy(work,"progdir:");
  266.         strcat(work,ourname);
  267.         strcat(work,"cfg");
  268.  
  269.         if(!(ctl=sfopen(work,"rt",DENY_WRITE)))
  270.         {
  271.            strcpy(work,ourname);
  272.            strcat(work,"cfg");
  273.  
  274.            ctl=sfopen(work,"rt",DENY_WRITE);
  275.         }
  276.  
  277.         if (ctl != NULL) {    /* OLSEN */
  278. #else
  279.         strcpy(work,ourname); strcat(work,"CFG");    /* extra configuration? */
  280.         if ((ctl=sfopen(work,"rt",DENY_WRITE)) != NULL) {
  281. #endif
  282.            while (fgets(buffer,200,ctl)) {
  283.                  ac = parse(buffer);
  284.                  if (ac && !config(ac,av))
  285.                     message(1,"-Unknown configurationfile option '%s'",av[0]);
  286.            }
  287.            fclose(ctl);
  288.         }
  289.  
  290.         strcpy(ctlname,ourname); strcat(ctlname,"CTL");    /* Opus ext <1.10 */
  291.         if ((ctl=sfopen(ctlname,"rt",DENY_WRITE)) != NULL) {
  292.            strcpy(buffer,ourname); strcat(buffer,"LOG");
  293.            opuslog = strdup(buffer);
  294.            goto opusctl;
  295.         }
  296.  
  297. #ifndef AMIGA
  298.         for (i = 1; i < argc; i++)
  299.             strupr(argv[i]);
  300. #endif    /* AMIGA */
  301.  
  302.         i = 1;
  303.         while (i < argc) {
  304.               res = config(argc - i,&argv[i]);
  305.               if (res) {
  306.                  i += res;
  307.  
  308.                  if (opustask >= 0) {/* Opus External Interface Version 1.10 */
  309.                     strcpy(ctlname,ourname);
  310.                     sprintf(&ctlname[((int) strlen(ctlname)) - 3],"%02x.CTL",opustask);
  311.                     if ((ctl=sfopen(ctlname,"rt",DENY_WRITE)) == NULL) {
  312.                        message(1,"-Can't open Opus ext file '%s'",ctlname);
  313.                        break;
  314.                     }
  315.  
  316.                     strcpy(buffer,ourname);
  317.                     sprintf(&buffer[((int) strlen(buffer)) - 3],"%02x.LOG",opustask);
  318.                     opuslog = strdup(buffer);
  319.  
  320. opusctl:            if (ffirst(opuslog))           /* delete any old logfile */
  321.                        unlink(opuslog);
  322.                     while (fgets(buffer,200,ctl)) {
  323.                           ac = parse(buffer);
  324.                           if (!ac) continue;
  325.                           if (!stricmp(av[0],"SEND")) {    /* OLSEN */
  326.                              if (!didsome) {
  327.                                 init();
  328.                                 hydra_init(hydra_options);
  329.                              }
  330.                              didsome = true;
  331.                              err = batch_hydra(av[1],ac > 2 ? av[2] : NULL);
  332.                           }
  333.                           else
  334.                              config(ac,av);
  335.  
  336.                           /* quit on errors during zsend or zrecv */
  337.                           if (err) break;
  338.                     }/*while(fgets(ctl))*/
  339.  
  340.                     fclose(ctl);
  341.                     unlink(ctlname);
  342.  
  343.                     if (!err) {
  344.                        if (!didsome) {
  345.                           init();
  346.                           hydra_init(hydra_options);
  347.                        }
  348.                        didsome = true;
  349.                        hydra(NULL,NULL);
  350.                     }
  351.                     hydra_deinit();
  352.                     break;
  353.                  }/*if(opustask>=0)*/
  354.  
  355.               }/*if(res)*/
  356.  
  357.               else {
  358.                  if (!strnicmp(argv[i],"TER",3)) {    /* OLSEN */
  359.                     init();
  360.                     didsome = true;
  361.                     hydracom();
  362.                     break;
  363.                  }
  364.  
  365.                  if (!strnicmp(argv[i],"SEN",3)) {    /* OLSEN */
  366.                     init();
  367.                     didsome = true;
  368.                     hydra_init(hydra_options);
  369.                     while (!err && ++i < argc) {
  370.                           if (*argv[i]=='@') {
  371.                              argv[i]++;
  372.                              if ((ctl=sfopen(argv[i],"rt",DENY_WRITE))==NULL) {
  373.                                 message(3,"!Couldn't open batch-ctlfile %s",argv[i]);
  374.                                 continue;
  375.                              }
  376.                              while (!err && fgets(buffer,200,ctl)) {
  377.                                    if (parse(buffer))
  378.                                       err = batch_hydra(av[0],ac > 1 ? av[1] : NULL);
  379.                              }
  380.                              fclose(ctl);
  381.                           }
  382.                           else
  383.                              err = batch_hydra(argv[i],NULL);
  384.                     }
  385.  
  386.                     if (!err)
  387.                        hydra(NULL,NULL);               /* end of batch stuff */
  388.                     hydra_deinit();
  389.                     break;
  390.                  }
  391.  
  392.                  if (!strnicmp(argv[i],"GET",3)) {    /* OLSEN */
  393.                     init();
  394.                     didsome = true;
  395.                     hydra_init(hydra_options);
  396.                     if (++i < argc) {
  397.                        splitpath(argv[i],work,single_file);
  398.                        if (work[0]) {
  399.                           p = &work[((int) strlen(work)) - 1];
  400. #ifndef AMIGA
  401.                           if (*p != '\\' && *p != '/' && *p != ':')
  402.                              strcat(work,"\\");
  403. #endif    /* AMIGA */
  404.                           download = strdup(work);
  405.                        }
  406.                     }
  407.                     hydra(NULL,NULL);
  408.                     hydra_deinit();
  409.                     break;
  410.                  }
  411.  
  412.                  message(1,"-Unknown commandline parameter '%s'",argv[i]);
  413.                  i++;
  414.               }
  415.         }
  416.  
  417.         if (didsome) {
  418.            if (!carrier() && dropdtr)
  419.               dtr_out(0);
  420.            sys_reset();
  421.            endprog(err);
  422.         }
  423.         else
  424.            cprint("Run %s without any options for usage screen\n",PRGNAME);
  425.  
  426.         if (logfp) fclose(logfp);
  427.  
  428.         exit (err);
  429. }
  430.  
  431.  
  432. void endprog (int errcode)
  433. {
  434. #if WIN_AGL
  435.         if (didsome) win_deinit();
  436. #endif
  437.         message(1,"+%s v%s %s : end (exitcode=%d)",
  438.                   PRGNAME,VERSION,HC_OS,errcode);
  439.         resultlog(false,NULL,0L,0L);
  440.         if (logfp) fclose(logfp);
  441.         exit (errcode);
  442. }
  443.  
  444.  
  445. int config (int argc, char *argv[])
  446. {
  447.         register int opt = 0;
  448.         register word temp;
  449.  
  450.         if (!strnicmp(argv[0],"-P",2)) {  /* -p<port>  */    /* OLSEN */
  451.            port = atoi(&argv[0][2]);
  452.            opt++;
  453.         }
  454.         else if (!strnicmp(argv[0],"-B",2)) {  /* -b<speed> */
  455. #ifdef AMIGA
  456.            com_speed = atol(&argv[0][2]);
  457. #else
  458.            com_speed = (word) atol(&argv[0][2]);
  459. #endif
  460.            opt++;
  461.         }
  462.         else if (!strnicmp(argv[0],"-T",2)) {  /* -t<task> */
  463.            opustask = atoi(&argv[0][2]);
  464.            opt++;
  465.         }
  466.         else if (!strnicmp(argv[0],"POR",3) && argc>=2) {  /* port */    /* OLSEN */
  467. #ifdef AMIGA
  468.            port = atoi(argv[1]);
  469. #else
  470.            port = atoi(argv[1]) - 1;
  471. #endif    /* AMIGA */
  472.            opt += 2;
  473.         }
  474. #ifdef AMIGA
  475.         else if (!strnicmp(argv[0],"UNI",3) && argc>=2) {  /* unit */    /* OLSEN */
  476.            port = atoi(argv[1]);
  477.            opt += 2;
  478.         }
  479. #endif    /* AMIGA */
  480.         else if (!strnicmp(argv[0],"DEV",3) && argc>=2) {  /* device */    /* OLSEN */
  481.            strcpy (device,argv[1]);
  482.            opt += 2;
  483.         }
  484.         else if (!strnicmp(argv[0],"PRI",3) && argc>=2) {  /* priority */    /* OLSEN */
  485.            pri = atoi(argv[1]);
  486.            opt += 2;
  487.         }
  488.         else if ((!strnicmp(argv[0],"SPE",3) || !strnicmp(argv[0],"BAU",3)) && argc>=2) {    /* OLSEN */
  489. #ifdef AMIGA
  490.            com_speed = atol(argv[1]);
  491. #else
  492.            com_speed = (word) atol(argv[1]);
  493. #endif
  494.            opt += 2;
  495.         }
  496.         else if (!strnicmp(argv[0],"LIN",3)) {  /* line */
  497. #ifdef AMIGA
  498.            cur_speed = atol(argv[1]);
  499. #else
  500.            cur_speed = (word) atol(argv[1]);
  501. #endif
  502.            opt += 2;
  503.         }
  504.         else if (!strnicmp(argv[0],"MOD",3) && argc >= 6) {  /* modem */
  505.            sscanf(argv[1],"%x",&port);
  506.            port--;
  507.            sscanf(argv[2],"%x",&com_speed);
  508.            sscanf(argv[3],"%x",&flowflags);
  509.            sscanf(argv[4],"%x",&dcdmask);
  510.            sscanf(argv[5],"%x",&cur_speed);
  511.            if (flowflags & 0x09)
  512.               hydra_options |= HOPT_XONXOFF;
  513.            opt += 6;
  514.         }
  515.         else if (!strnicmp(argv[0],"PAR",3)) {   /* parity */    /* OLSEN */
  516.            parity = true;
  517.            hydra_options |= HOPT_HIGHBIT;
  518.            opt++;
  519.         }
  520.         else if (!strnicmp(argv[0],"HAN",3) && argc >= 2) {   /* handshake */    /* OLSEN */
  521.            if      (!strnicmp(argv[1],"SOF",3)) flowflags |= 0x09;    /* OLSEN */
  522.            else if (!strnicmp(argv[1],"HAR",3)) flowflags |= 0x02;    /* OLSEN */
  523.            else if (!strnicmp(argv[1],"BOT",3)) flowflags |= 0x0b;    /* OLSEN */
  524.            else if (!strnicmp(argv[1],"NON",3)) flowflags = 0;    /* OLSEN */
  525.            if (flowflags & 0x09)
  526.               hydra_options |= HOPT_XONXOFF;
  527.            opt += 2;
  528.         }
  529.         else if (!strnicmp(argv[0],"NOI",3)) {   /* noinit */    /* OLSEN */
  530.            noinit = true;
  531.            opt++;
  532.         }
  533.         else if (!strnicmp(argv[0],"DRO",3)) {   /* dropdtr */    /* OLSEN */
  534.            dropdtr = true;
  535.            opt++;
  536.         }
  537.         else if (!strnicmp(argv[0],"NOB",3)) {   /* nobell */    /* OLSEN */
  538.            nobell = true;
  539.            opt++;
  540.         }
  541. #ifdef AMIGA
  542.         else if (!strnicmp(argv[0],"QUI",3)) {   /* quiet */    /* OLSEN */
  543.            quiet = true;
  544.            opt++;
  545.         }
  546. #endif
  547.         else if (!strnicmp(argv[0],"MAI",3)) {   /* mailer */    /* OLSEN */
  548.            mailer = true;
  549.            opt++;
  550.         }
  551.         else if (!strnicmp(argv[0],"NOO",3)) {   /* nooriginator */    /* OLSEN */
  552.            nooriginator = true;
  553.            opt++;
  554.         }
  555.         else if (!strnicmp(argv[0],"HDX",3)) {   /* hdxlink */    /* OLSEN */
  556.            hdxsession = true;
  557.            opt++;
  558.         }
  559.         else if (!strnicmp(argv[0],"TXW",3) && argc >= 2) {  /* txwindow */
  560.            hydra_txwindow = atol(argv[1]);
  561.            if (hydra_txwindow < 0L)
  562.               hydra_txwindow = 0L;
  563.            opt += 2;
  564.         }
  565.         else if (!strnicmp(argv[0],"RXW",3) && argc >= 2) {  /* rxwindow */
  566.            hydra_rxwindow = atol(argv[1]);
  567.            if (hydra_rxwindow < 0L)
  568.               hydra_rxwindow = 0L;
  569.            opt += 2;
  570.         }
  571.         else if (!strnicmp(argv[0],"NOC",3)) {   /* nocarrier */    /* OLSEN */
  572.            nocarrier = true;
  573.            opt++;
  574.         }
  575.         else if (!stricmp(argv[0],"LOG") && argc >= 2) {   /* log */    /* OLSEN */
  576.            if (logfp) fclose(logfp);
  577.            logfp = sfopen(argv[1],"at",DENY_WRITE);
  578.            if (logfp == NULL)
  579.               message(3,"-Couldn't open log-file %s",argv[1]);
  580.            opt += 2;
  581.         }
  582.         else if (!strnicmp(argv[0],"LEV",3) && argc>=2) {  /* level */    /* OLSEN */
  583.            temp = atoi(argv[1]);
  584.            if (temp >=0 && temp <= 6)
  585.               loglevel = temp;
  586.            else
  587.               message(6,"-Invalid log-level %d",temp);
  588.            opt +=2;
  589.         }
  590.         else if (!strnicmp(argv[0],"RES",3) && argc>=2) {  /* DSZ-format log */    /* OLSEN */
  591.            if (result) free(result);
  592.            result = strdup(argv[1]);
  593.            opt += 2;
  594.         }
  595.         else if ((!strnicmp(argv[0],"REC",3) || !strnicmp(argv[0],"UPL",3)) && argc>=2) {    /* OLSEN */
  596.            char *p;
  597.  
  598.            strcpy(work,argv[1]);
  599. #ifndef AMIGA
  600.            p = &work[((int) strlen(work)) - 1];
  601.            if (*p != '\\' && *p != '/' && *p != ':')
  602.               strcat(work,"\\");
  603. #else
  604.            p = &work[((int) strlen(work)) - 1];
  605.            if (*p != '/' && *p != ':')
  606.               strcat(work,"/");
  607. #endif    /* AMIGA */
  608.            download = strdup(work);
  609.            opt += 2;
  610.         }
  611.         else if (!strnicmp(argv[0],"NOR",3)) {             /* noresume */    /* OLSEN */
  612.            noresume = true;
  613.            opt++;
  614.         }
  615.         else if (!strnicmp(argv[0],"NOS",3)) {             /* nostamp */    /* OLSEN */
  616.            nostamp = true;
  617.            opt++;
  618.         }
  619.         else if (!strnicmp(argv[0],"OPT",3) && argc>=2) {  /* option  */    /* OLSEN */
  620.            if      (!stricmp(argv[1],"XONXOFF")) hydra_options |= HOPT_XONXOFF;    /* OLSEN */
  621.            else if (!stricmp(argv[1],"TELENET")) hydra_options |= HOPT_TELENET;
  622.            else if (!stricmp(argv[1],"CTLCHRS")) hydra_options |= HOPT_CTLCHRS;
  623.            else if (!stricmp(argv[1],"HIGHCTL")) hydra_options |= HOPT_HIGHCTL;
  624.            else if (!stricmp(argv[1],"HIGHBIT")) hydra_options |= HOPT_HIGHBIT;
  625.            else message(6,"-Invalid link option '%s'\n",argv[1]);
  626.            opt += 2;
  627.         }
  628.         else if (!strnicmp(argv[0],"RET",3)) {  /* retries */    /* OLSEN */
  629.            extern long max_retries;
  630.  
  631.            temp = atoi(argv[1]);
  632.            if (temp >=0)
  633.               max_retries = temp;
  634.            else
  635.               message(6,"-Invalid number of retries %d",temp);
  636.            opt++;
  637.         }
  638.  
  639.         return (opt);
  640. }
  641.  
  642.  
  643. void init(void)
  644. {
  645.         /*if (logfp) fputs("\n",logfp);*/
  646.         message(1,"+%s v%s %s : begin",PRGNAME,VERSION,HC_OS);
  647.  
  648.         sys_init();
  649.  
  650. #if WIN_AGL
  651.         if (!win_init(10,CUR_NORMAL,CON_ANSI|CON_WRAP|CON_SCROLL|CON_UNBLANK,
  652.                       CHR_NORMAL,KEY_ANSI)) {
  653.            cprint("Can't initialize window system!\n");
  654.            exit (1);
  655.         }
  656. #endif
  657.  
  658.         dtr_out(1);
  659.  
  660.         if (com_speed)
  661.            com_setspeed(com_speed);
  662.         if (!com_speed)
  663.            com_speed = 2400U;
  664.         if (!cur_speed)
  665.            cur_speed = com_speed;
  666. }/*init()*/
  667.  
  668.  
  669. int batch_hydra (char *filespec, char *alias)
  670. {
  671.         char  path[PATHLEN];
  672.         char *p;
  673.         char  doafter;
  674.         int   fd;
  675.  
  676. #ifdef AMIGA
  677.     if(!filespec)
  678.         return(0);
  679. #endif
  680.  
  681.         switch (*filespec) {
  682.                case '^':
  683.                case '#': doafter = *filespec++;
  684.                          break;
  685.                default:  doafter = 0;
  686.                          break;
  687.         }
  688.  
  689.         splitpath(filespec,path,work);
  690.         for (p = ffirst(filespec); p; p = fnext()) {
  691.             mergepath(work,path,p);
  692.             switch (hydra(work,alias)) {
  693.                    case XFER_ABORT:
  694. #ifdef AMIGA
  695.                         return (5);
  696. #else
  697.                         return (1);
  698. #endif
  699.                    case XFER_SKIP:
  700.                         break;
  701.  
  702.                    case XFER_OK:
  703.                         switch (doafter) {
  704.                                case '^':  /* Delete */
  705.                                     if (unlink(work))
  706.                                        message(6,"!HSEND: Could not delete %s",work);
  707.                                     else
  708.                                        message(1,"+Sent-H deleted %s",work);
  709.                                     break;
  710.  
  711.                                case '#':  /* Truncate */
  712.                                     if ((fd = dos_sopen(work,2)) < 0) {
  713.                                        message(6,"!HSEND: Error truncating %s",work);
  714.                                        break;
  715.                                     }
  716.                                     dos_close(fd);
  717.                                     message(1,"+Sent-H truncated %s",work);
  718.                                     break;
  719.  
  720.                                default:
  721.                                     message(1,"+Sent-H %s",work);
  722.                                     break;
  723.                         }
  724.                         break;
  725.             }
  726.         }
  727.  
  728.         return (0);
  729. }/*batch_hydra()*/
  730.  
  731.  
  732. void hydracom (void)
  733. {
  734.         static   char *hauto = "\030cA\\f5\\a3\030a";
  735.         register char *hseek = hauto;
  736.         register int   c, i;
  737.         boolean  echo;
  738.         int      mask;
  739. /*        char     queue[80];*/
  740.         static char queue[1024];    /* OLSEN */
  741.         long t;
  742.  
  743.         message(0,"+Entering terminal mode");
  744.         queue[0] =  '\0';
  745.         echo = false;
  746.         mask = parity ? 0x7f : 0xff;
  747.  
  748.         do {
  749. #if WIN_AGL
  750.            while (!win_keyscan()) {
  751. #elif defined(AMIGA)
  752.            while (!ConScanKey()) {
  753. #else
  754.            while (!kbhit()) {
  755. #endif
  756.                  if (!carrier()) {
  757.                     cprint("\007\n");
  758.                     message(1,"-Carrier lost, exiting (should use 'NOCarrier'?)");
  759.                     return;
  760.                  }
  761.  
  762.                  if ((c = com_getbyte()) != EOF) {
  763.                     c &= mask;
  764.                     if (c == 12)
  765.                        cprint("\033[2J");
  766.                     else
  767.                        cprint("%c",c);
  768.  
  769.                     if ((c & 0x7f) == *hseek) {
  770.                        if (!*++hseek) {
  771.                           hseek = hauto;
  772.                           goto autostart;
  773.                        }
  774.                     }
  775.                     else hseek = hauto;
  776.                  }
  777.                  else
  778.                     sys_idle();
  779.            }/*while*/
  780.  
  781. #ifdef AMIGA
  782.            switch (c = ConGetKey()) {
  783. #else
  784.            switch (c = get_key()) {
  785. #endif    /* AMIGA */
  786.                   case EOF: break;
  787.                   case Alt_X: break;
  788.                   case Alt_C: cprint("\033[2J");
  789.                               break;
  790.                   case Alt_B: if (parity)
  791.                                  cprint("\r**Can't toggle 8th bit strip with parity 7E1\n");
  792.                               else {
  793.                                  mask ^= 0x80;
  794.                                  cprint("\r**Strip 8th bit %s\n",
  795.                                         (mask & 0x80) ? "Off" : "On");
  796.                               }
  797.                               break;
  798.                   case Alt_E: echo = !echo;
  799.                               cprint("\r**Local echo %s\n",
  800.                                      echo ? "On" : "Off");
  801.                               break;
  802.                   case Alt_H: dtr_out(0);
  803.                               for (t = time(NULL) + 1; time(NULL) < t; );
  804.                               dtr_out(1);
  805.                               cprint("\r**Dropped dtr\n");
  806.                               break;
  807. #ifdef AMIGA
  808.                   case PgUp:
  809.                   {
  810.                      char *GetFiles(char *Buffer,int MaxLen);
  811.  
  812.                      if(GetFiles(queue,1020))
  813.                         cprint("\r**Queue will be sent during next session\n");
  814.                      else
  815.                      {
  816.                         queue[0] = 0;
  817.  
  818.                         cprint("\r**Send queue empty\n");
  819.                      }
  820.                      break;
  821.                   }
  822. #else
  823.                   case PgUp:  switch (get_str("**Send",queue,1020)) {    /* OLSEN */
  824.                                      case -1: cprint("\r**Send queue cleared\n");
  825.                                               break;
  826.                                      case  0: cprint("\r**Send queue empty\n");
  827.                                               break;
  828.                                      default: cprint("\r**Queue will be sent during next session\n");
  829.                                               break;
  830.                               }
  831.                               break;
  832. #endif    /* AMIGA */
  833.                   case PgDn:
  834. autostart:                    hydra_init(hydra_options);
  835.                               c = 0;
  836.                               if (parse(queue))
  837.                                  for (i = 0; av[i] && ((c = batch_hydra(av[i],NULL)) == 0); i++);
  838.                               if (!c) hydra(NULL,NULL);
  839.                               hydra_deinit();
  840.                               queue[0] = '\0';
  841.                               cprint("\r**Finished\n");
  842.                               break;
  843.                   default:    if (c < 0x100) {
  844.                                  com_putbyte((byte) c);
  845.                                  if (echo) {
  846.                                     cprint("%c",c);
  847.                                     if (c == '\r') cprint("\n");
  848.                                  }
  849.                               }
  850.                               break;
  851.            }
  852.         } while (c != Alt_X && c != EOF);
  853.  
  854.         cprint("\n");
  855.         message(0,"+Exiting terminal mode");
  856. }/*hydracom()*/
  857.  
  858. /* end of hydracom.c */
  859.